package jhunter.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jhunter.common.id.Id;
import jhunter.dao.DaoFactory;
import jhunter.dao.DataAccess;
import jhunter.dao.EntityExt;
import jhunter.dao.bo.BaseObject;
import jhunter.dao.page.Page;
import jhunter.service.EasyFormDataService;
import jhunter.web.mvc.ActionContext;

import org.apache.commons.lang.StringUtils;

import schema.ext.ModuleExt;
import schema.vo.module.EasyForm;
import schema.vo.module.Element;
import schema.vo.module.EventHandler;

import com.alibaba.fastjson.JSON;

public class EasyFormDataServiceImpl implements EasyFormDataService {

	private DaoFactory daoFactory;

	private Id idGenerator;

	@Override
	public BaseObject findById(ActionContext context) {
		EasyForm easyForm = getEasyForm(context);
		DataAccess dao = daoFactory.getDao(easyForm.getEntity());
		String id = (String) context.getParameters().get(dao.getEntity().getPrimaryProp());
		return dao.findById(Long.valueOf(id));
	}

	@Override
	public void add(ActionContext context) {
		EasyForm easyForm = getEasyForm(context);
		DataAccess dao = daoFactory.getDao(easyForm.getEntity());
		BaseObject bo = buildBoByForm(dao.getEntity(), easyForm, context);
		if (!bo.containsKey(dao.getEntity().getPrimaryProp())) {
			bo.addValue(dao.getEntity().getPrimaryProp(), idGenerator.nextVal());
		}
		dao.insert(bo);
	}

	@Override
	public void update(ActionContext context) {
		EasyForm easyForm = getEasyForm(context);
		DataAccess dao = daoFactory.getDao(easyForm.getEntity());
		BaseObject bo = buildBoByForm(dao.getEntity(), easyForm, context);
		if (!bo.containsKey(dao.getEntity().getPrimaryProp())) {
			throw new RuntimeException("id 不存在");
		}
		dao.updateIgnoreNull(bo, Long.valueOf((String) bo.get(dao.getEntity().getPrimaryProp())));
	}

	@Override
	public void delete(ActionContext context) {

		EasyForm easyForm = getEasyForm(context);
		DataAccess dao = daoFactory.getDao(easyForm.getEntity());
		String pk = dao.getEntity().getPrimaryProp();
		Object o = context.getParameters().get(pk);
		if (o instanceof String) {
			dao.delete(Long.valueOf((String) o));
		} else {
			String[] ids = (String[]) o;
			for (String id : ids) {
				dao.delete(Long.valueOf((String) id));
			}
		}

	}

	public BaseObject buildBoByForm(EntityExt entity, EasyForm form, ActionContext context) {
		BaseObject bo = BaseObject.create();
		List<Element> eles = form.getDataPanel().getElement();
		for (Element element : eles) {
			String prop = element.getEntityProperty();
			// String type = entity.getPropsMap().get(prop).getType();
			// Object value = TypeHandlerFactory.getTypeHandler(type);
			Object value = context.getParameters().get(element.getName());
			if (value != null) {
				if (value instanceof String) {
					bo.addValue(prop, value);
				} else {
					bo.addValue(prop, ((String[]) value)[0]);
				}
			}
		}
		return bo;
	}

	public Page<BaseObject> getPageData(ActionContext context) {
		Page<BaseObject> page = getPage(context);
		EasyForm form = getEasyForm(context);
		DataAccess dao = daoFactory.getDao(form.getEntity());
		dao.query(page, new EasyFormCondition(form, dao, context));
		return page;
	}

	public String getJsonData(ActionContext context) {
		Page<BaseObject> page = getPageData(context);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("count", page.getTotalCount());
		List<List<Object>> list = new ArrayList<List<Object>>();
		EasyForm form = getEasyForm(context);
		for (BaseObject bo : page.getResult()) {
			List<Object> object = new ArrayList<Object>();
			List<Element> elements = form.getDataPanel().getElement();
			for (Element element : elements) {
				String p = element.getEntityProperty();
				Object value = bo.get(p);
				// TODO display el
				List<EventHandler> evs = element.getEventHandler();
				if (evs != null && evs.size() > 0) {
					StringBuilder sb = new StringBuilder("<div ");
					for (EventHandler eventHandler : evs) {

						sb.append(eventHandler.getEvent()).append("=");
						sb.append("GLOBAL.");
						sb.append(eventHandler.getFunction()).append("(");
						String args = eventHandler.getFunctionArg();
						if (args != null && args.trim().length() > 0) {
							String[] argArray = args.split(",");
							for (int i = 0; i < argArray.length; i++) {
								String arg = argArray[i];
								if (arg.startsWith("@")) {
									String a = arg.substring(1);
									arg = bo.get(a).toString();
								}
								sb.append("'").append(arg.trim()).append("'");
								if (i != argArray.length - 1) {
									sb.append(",");
								}
							}
						}
						sb.append(")");
					}
					sb.append(">");
					sb.append(value);
					sb.append("</div>");
					object.add(sb.toString());
				} else {
					object.add(value.toString());
				}
			}
			list.add(object);
		}
		map.put("data", list);

		return JSON.toJSONString(map, true);
	}

	public Page<BaseObject> getPage(ActionContext context) {
		Integer pageSize = Integer.valueOf((String) context.getParameters().get("pageSize"));
		Integer pageIndex = Integer.valueOf((String) context.getParameters().get("pageIndex"));
		Page<BaseObject> page = new Page<BaseObject>();
		page.setPageNo(pageIndex);
		page.setPageSize(pageSize);
		return page;
	}

	public EasyForm getEasyForm(ActionContext context) {
		String easyForm = (String) context.getParameters().get("easyForm");
		if (StringUtils.isEmpty(easyForm)) {
			easyForm = context.getActionConfig().getAction().getName();
		}
		ModuleExt module = context.getActionConfig().getModuleExt();
		EasyForm form = module.getFormByName(easyForm);
		return form;
	}

	public DaoFactory getDaoFactory() {
		return daoFactory;
	}

	public void setDaoFactory(DaoFactory daoFactory) {
		this.daoFactory = daoFactory;
	}

	public Id getIdGenerator() {
		return idGenerator;
	}

	public void setIdGenerator(Id idGenerator) {
		this.idGenerator = idGenerator;
	}

}
